<?php

/**
 * This file is part of the Pagizer package.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright   Copyright (c) 2010 Advisa (http://www.advisa.fr)
 * @author      Pagizer Core Team <team@pagizer.org>
 * @package     pagizer
 * @subpackage  searchEngine
 */

class m_searchEngine_services_searchService extends f_core_Service
{
    private $resultsPerPage = 10;
    private $words;
    private $nbMaxPage;

    /**
     *
     * @return m_searchEngine_services_searchService
     */
    public static function getInstance()
    {
        return new self();
    }

    /**
     * Used to set number of results per page
     * @param integer $value
     * @return m_searchEngine_services_searchService
     */
    public function setResultsPerPage($value)
    {
        $this->resultsPerPage = $value;
        return $this;
    }

    /**
     * Add a word to search
     * @param string $word
     * @return m_searchEngine_services_searchService
     */
    public function addWordToSearch($word)
    {
        $this->words[] = $word;
        return $this;
    }

    private function countResults()
    {
        if(count($this->words) > 0)
        {
            $words = "+".join(" +",explode(" ",$this->words[0]));

            $dbProvider = f_database_Provider::getInstance();
            
            $nbResults = $dbProvider->setQuery("SELECT COUNT(IF(MATCH(description,content) AGAINST(:words IN BOOLEAN MODE),1, NULL)) AS count FROM f_index")
                                    ->execute(array("words" => $words))
                                    ->getQueryResults(PDO::FETCH_COLUMN);

            return intval($nbResults[0]);
        }
    }

    private function searchInNaturalMode()
    {
        if(count($this->words) > 0)
        {
            $words = "+".join(" +",explode(" ",$this->words[0]));

            $dbProvider = f_database_Provider::getInstance();

            return $dbProvider  ->setQuery("SELECT *, MATCH(description,content) AGAINST(:words) AS relev FROM f_index WHERE MATCH(description,content) AGAINST (:words)>0 ORDER BY relev DESC")
                                ->execute(array("words" => $words))
                                ->getQueryResults(PDO::FETCH_CLASS, "m_searchEngine_documents_Index");
        }
    }

    private function searchInBooleanMode()
    {
        if(count($this->words) > 0)
        {
            $words = "+".join(" +",explode(" ",$this->words[0]));

            $dbProvider = f_database_Provider::getInstance();

            return $dbProvider  ->setQuery("SELECT *, MATCH(description,content) AGAINST(:words IN BOOLEAN MODE) FROM f_index WHERE MATCH(description,content) AGAINST (:words IN BOOLEAN MODE)>0")
                                ->execute(array("words" => $words))
                                ->getQueryResults(PDO::FETCH_CLASS, "m_searchEngine_documents_Index");
        }
    }
        
    public function getResults($page = 1)
    {
        $nbResults = $this->countResults();

        $result["currentPage"] = 1;
        $result["nbResults"] = 0;
        $result["results"] = array();
        $result["nbPages"] = 1;

        if($nbResults > 0)
        {
            $nbPages = ceil($nbResults/$this->resultsPerPage);

            if($page > $nbPages) $page = $nbPages;

            $offset = ($page-1)*$this->resultsPerPage;

            $results = $this->searchInNaturalMode();

            if(count($results) == 0)
            {
                $results = $this->searchInBooleanMode();
            }
	    
            $results = array_slice($results, $offset, $this->resultsPerPage);

            for ($i = 1 ; $i <= $nbPages ; $i++)
            {
                $result["pageNumbers"][] = $i;
            }

            $result["currentPage"] = $page;
            $result["nbResults"] = $nbResults;
            $result["results"] = $results;
            $result["nbPages"] = $nbPages;
        }

        return $result;
    }
}